package com.panopset.flywheel;

import static com.panopset.Util.log;

import java.io.StringWriter;

import com.panopset.ReflectionInvoker;

/**
 * <h5>e - Execute</h5>
 * <p>
 * Excecute any public static method, which returns a String and takes 0 or more
 * String parameters. If parameters match variable names, then they will be
 * replaced by the variable value, otherwise the parameter will be used as is.
 * </p>
 * <p>
 * You may register objects that will be available using the
 * Flywheel.Builder.registerObject function. The keys must be one word. Instance
 * methods may be called from registered objects.
 * </p>
 *
 * <pre>
 *
 * ${&#064;p name}panopset${&#064;q}
 *
 * ${&#064;e com.panopset.Strings.capitalize(name)}
 *
 * </pre>
 *
 * The above script will output:
 *
 * <pre>
 *
 * Panopset
 *
 * </pre>
 *
 * @author Karl Dinwiddie
 */
public class CommandExecute extends TemplateDirectiveCommand {

    /**
     * Short HTML text for publishing command format in an HTML document.
     *
     * @return <b>${&#064;e com.panopset.Strings.capitalize(name)}</b>.
     */
    public static String getShortHTMLText() {
        return "${&#064;e com.panopset.Strings.capitalize(name)}";
    }

    /**
     * Command Execute constructor.
     *
     * @param source
     *            Command source.
     * @param innerPiece
     *            Inner piece of the command.
     * @param template
     *            Template this command was declared in.
     */
    public CommandExecute(final String source, final String innerPiece,
            final Template template) {
        super(source, innerPiece, template);
    }

    @Override
    public final void resolve(final StringWriter sw) {
        try {
            String s = getParams();
            int i = s.lastIndexOf(".");
            if (i > -1) {
                String key = s.substring(0, i);
                Object object = getTemplate().getFlywheel()
                        .getRegisteredObjects().get(key);
                if (object != null) {
                    sw.append(new ReflectionInvoker.Builder().object(object)
                            .methodAndParms(s.substring(i + 1))
                            .mapProvider(getTemplate().getFlywheel())
                            .construct().exec());
                    return;
                }
            }
            sw.append(new ReflectionInvoker.Builder()
                    .classMethodAndParms(getParams())
                    .mapProvider(getTemplate().getFlywheel()).construct()
                    .exec());
        } catch (Exception e) {
            if (getTemplate() != null) {
                log("Line: " + getLineNumber() + " "
                        + getTemplate().getStringLineSupplier().getFullName());
                log(getTemplate().getRelativePath());
                if (getTemplate().getCommandFile() != null) {
                    log("Output file: " + getTemplate().getCommandFile());
                    log("source: " + getSource());
                }
            }
            log(e);
            if (getTemplate() != null && getTemplate().getFlywheel() != null) {
                getTemplate().getFlywheel().stop(e.getMessage());
            }
            log("Failure executing " + getSource());
        }
    }

}
